/*!
 * \file set_relation_isl_visitor.h
 *
 * \brief Declarations of the SetRelationISLVisitor
 *
 * \date Started: 7/12/2010
 * \date Last Modified: 7/12/2010
 * \authors Alan LaMielle Nicholas Jeanette
 *
 * Copyright (c) 2010, Colorado State University <br>
 * All rights reserved. <br>
 * See ../../COPYING for details. <br>
 */

#ifndef SET_RELATION_ISL_VISITOR_H_
#define SET_RELATION_ISL_VISITOR_H_

#include <iegenlib/iegenlib.h>

namespace iegenlib{

/*!
 * \class SetRelationISLVisitor
 * \brief This class returns the original Set or Relation by traversing the Set
 *        or Relation structure
 *
 * This class uses the structure defined in the Set and Relation classes to
 * recreate the original input string that was presented to create the structure
 * in the first place. It is mostly used as a testing device and a sanity check.
 */
class SetRelationISLVisitor: public SRVisitor{
public:

   SetRelationISLVisitor();

   /*!
   * Used for general tasks to be done going out of every visited node
   * @param node node to do tasks on
   */
   void defaultOut();

   /*!
   * Used for general tasks to be done going In every visited node
   * @param node node to do tasks on
   */
   void defaultIn();

   /*!
   * Function called by the SetCase method for the Set node this is where '{'
   * gets appended to the output string
   * @param node Set pointer
   */
   void SetIn(const Set* );

   /*!
   * Function called by the SetCase method for the Set node this is where '}'
   * gets appended to the output string
   * @param Set pointer
   */
   void SetOut(const Set*);

   /*!
   * Function called by the RelationCase method for the Relation.
   * @param Relation pointer
   */
   void RelationIn(const Relation*);

   /*!
   * Function called by the RelationCase method for the Relation
   * @param Relation pointer
   */
   void RelationOut(const Relation* x);

   /*!
   * Function called by the SymbolTableCase method for the SymbolTable. This is
   * where the '[' gets appended to the output string
   * @param SymbolTable pointer
   */
   void SymbolTableIn(SymbolTable* x);

   /*!
   * Function called by the apply method for the SRConjuntion. This applys the
   * 'and' to the sting if there are multiple conjuntions
   * @param SRConjuntion pointer
   */
   void SRConjunctionCase(const SRConjunction* x);

   /*!
   * Function called by the SREqualityCase method for the SREquality. This
   * gets and appends the equaltiy vector with '=0' to the output string
   * @param SREquality pointer
   */
   void SREqualityIn(const SREquality* x);

   /*!
   * Function called by the SRInequalityCase method for the SRInequality. This
   * gets and appends the inequaltiy vector with '>=0' to the output string
   * @param SRInequality pointer
   */
   void SRInequalityIn(const SRInequality* x);

   /*!
   * Function called by the ConstValCase method for the ConstVal. This goes
   * through and adds the ConstVal in the brackets. Also checks if the ConstVal
   * needs to go in the first or second set of brackets.
   * @param TupleVar pointer
   */
   void TupleTypeOut(const TupleType* x);

   /*!
    * This gets the string of the output of the visitor
    * @return string of the isl representation
    */
   inline string getISL(){return out;};

private:

   ///this is the string we use to store our output in
   string out;

   ///a boolean flag for the first tuple
   bool firstTup;

   ///a pointer to the symbol table
   SymbolTable* ST;

   ///an integer that holds the in Arity
   int iA;

   ///an integer that holds the out Arity
   int oA;

   ///an integer that is used to know when to switch to out arity
   int arityCounter;

   bool firstConj;
};

}//end namespace iegenlib

#endif /* SET_RELATION_ISL_VISITOR_H_ */
